from django.shortcuts import render
from django.views import View
from django.http import HttpResponseBadRequest, JsonResponse
# Create your views here.
import json
import pickle, base64
from django_redis import get_redis_connection
from apps.goods.models import SKU, GoodsCategory
# 用户购物车

class CartsSimpleView(View):
    def get(self, request):
        '''简单购物车展示'''
        # 从redis中那数据
        user = request.user
        if user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            carts_dict = redis_conn.hgetall('carts_%s' % user.id)
            # 生成数据
            cart_skus = []
            for sku_id, count in carts_dict.items():
                sku = SKU.objects.get(id=sku_id)
                cart_skus.append({
                    "id": sku.id,
                    "name": sku.name,
                    "count": int(count),
                    "default_image_url": sku.default_image.url
                })
        else:
            carts_cookie = request.COOKIES.get('carts')
            # 解密
            carts_dict = pickle.loads(base64.b64decode(carts_cookie.encode()))
            cart_skus = []
            for sku_id, cs_dict in carts_dict.items():
                sku = SKU.objects.get(id=sku_id)
                cart_skus.append({
                    "id": sku.id,
                    "name": sku.name,
                    "count": cs_dict['count'],
                    "default_image_url": sku.default_image.url
                })

        return JsonResponse({'code': 0, 'errmsg': 'OK', 'cart_skus': cart_skus})


class UserAllChoiceView(View):
    def put(self, request):
        '''全选'''
        user = request.user
        selected_dict = json.loads(request.body.decode())
        selected = selected_dict.get('selected')

        if user.is_authenticated:
            # redis
            redis_conn = get_redis_connection('carts')
            sku_ids = [sku_id for sku_id in redis_conn.hgetall('carts_%s' % user.id).keys()]
            if selected:

                for sku_id in sku_ids:
                    redis_conn.sadd('selected_%s' % user.id, sku_id)
                return JsonResponse({'code': 0, 'errmsg': '全选购物车成功'})

            else:
                redis_conn.srem('selected_%s' % user.id, *sku_ids)
                return JsonResponse({'code': 0, 'errmsg': '取消全选购物车成功'})


        else:
            # cookie
            sku_cookie = request.COOKIES.get('carts')
            sku_dict = pickle.loads(base64.b64decode(sku_cookie.encode()))

            if selected:
                for sku_id in sku_dict.keys():
                    sku_dict[sku_id]['selected'] = True
            else:
                for sku_id in sku_dict.keys():
                    sku_dict[sku_id]['selected'] = None
            # 加密数据
            sku_b = base64.b64encode(pickle.dumps(sku_dict)).decode()

            response = JsonResponse({'code': 0,
                                     'errmsg': 'ok'})
            response.set_cookie('carts_%s' % user.id, sku_b, max_age=7 * 24 * 3600)
            return response








class UserCartsView(View):
    def delete(self, request):
        '''删除商品'''
        user = request.user
        # 拿到sku_id
        sku_dict = json.loads(request.body.decode())
        sku_id = sku_dict.get('sku_id')
        if user.is_authenticated:
            # 删redis里的
            redis_conn = get_redis_connection('carts')
            redis_conn.hdel('carts_%s' % user.id, sku_id)
            redis_conn.srem('selected_%s' % user.id, sku_id)
            # 删除结束后，没有响应的数据，只需要响应状态码即可
            return JsonResponse({'code': 0, 'errmsg': '删除购物车成功'})
        else:
            # cookie中删除
            sku_cookies = request.COOKIES.get('carts')
            # 解码
            sku_dict = pickle.loads(base64.b64decode(sku_cookies.encode()))
            # 删除数据
            del sku_dict[sku_id]
            # 加密
            sku_d = base64.b64encode(pickle.dumps(sku_dict)).decode()

            response = JsonResponse({'code': 0, 'errmsg': '删除购物车成功'})
            response.set_cookie('carts', sku_d, max_age=7 * 24 * 3600)
            return response






    def put(self, request):
        '''修改购物车数据'''
        user = request.user
        # 拿到数据
        sku_dict = json.loads(request.body.decode())
        sku_id = sku_dict.get('sku_id')
        count = sku_dict.get('count')
        selected = sku_dict.get('selected')
        # 判断参数是否齐全
        if not all([sku_id, count]):
            return HttpResponseBadRequest('缺少必传参数')
        # 判断sku_id是否存在
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return HttpResponseBadRequest('商品sku_id不存在')

        if user.is_authenticated:
            # 修改redis
            redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            pl.hset('carts_%s' % user.id, sku_id, count)

            # 判断selected
            if selected:
                pl.sadd('selected_%s' % user.id, sku_id)
            else:
                # 删掉sku_id
                pl.srem('selected_%s' % user.id, sku_id)
            pl.execute()

            # 创建响应数据
            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price,
                'amount': sku.price * count,
            }
            return JsonResponse({'code': 0,
                                 'errmsg': 'ok',
                                 'cart_sku': cart_sku})

        else:
            # 修改cookies
            sku_dict = request.COOKIES.get('carts')
            # 解码
            sku_info = pickle.loads(base64.b64decode(sku_dict.encode()))
            sku_info[sku_id]['count'] = count
            sku_info[sku_id]['selected'] = selected
            # 加密数据
            sku_b = base64.b64encode(pickle.dumps(sku_info)).decode()

            # 生成数据
            sku = SKU.objects.get(id=sku_id)
            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price,
                'amount': sku.price * count,
            }

            response =  JsonResponse({'code': 0,
                                 'errmsg': 'ok',
                                 'cart_sku': cart_sku})
            response.set_cookie('carts', sku_b, max_age=7 * 24 * 3600)
            return response

    def get(self, request):
        '''展示购物车'''
        user = request.user
        if user.is_authenticated:
            # 从redis中拿
            redis_conn = get_redis_connection('carts')

            # 拿到商品id和数量哈希是字典
            sku_info = redis_conn.hgetall('carts_%s' % user.id)
            # 拿到勾选选项列表
            cart_selected = redis_conn.smembers('selected_%s' % user.id)

            # 生成数据
            cart_skus = []
            for skus_id, count in sku_info.items():
                # 拿到数据对象
                sku = SKU.objects.get(id=skus_id)
                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'count': int(count),
                    'selected': skus_id in cart_selected,  # 将True，转'True'，方便json解析
                    'default_image_url': sku.default_image.url,
                    'price': sku.price,
                    'amount': sku.price * int(count)
                })


        else:
            # 从cookie中拿
            sku_cookie = request.COOKIES.get('carts')
            # 解码
            sku_info = pickle.loads(base64.b64decode(sku_cookie))
            # 生成数据
            cart_skus = []
            for sku_id in sku_info.keys():
                count = sku_info[sku_id]['count']
                selecteds = sku_info[sku_id]['selected']
                # 拿到数据对象
                sku = SKU.objects.get(id=sku_id)

                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'count': count,
                    'selected': selecteds,  # 将True，转'True'，方便json解析
                    'default_image_url': sku.default_image.url,
                    'price': sku.price,
                    'amount': sku.price * count
                })
                print(sku.price * count)
        return JsonResponse({'code': 0,
                            'errmsg': 'ok',
                            'cart_skus': cart_skus})




    def post(self, request):
        '''添加购物车'''

        # 分为登录用户和未登录用户登录用户存在redis中未登录存在cookie中
        # 拿到数据
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id') # 商品id
        count = json_dict.get('count') # 数量
        selected = json_dict.get('selected') # 是否勾选

        # 效验数据
        if not all([sku_id, count]):
            return HttpResponseBadRequest('数据不全')
        # 检查商品
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return HttpResponseBadRequest('商品不存在')
        # 检查参数
        try:
            count = int(count)
        except Exception:
            return HttpResponseBadRequest('参数不正确')

        if selected:
            if not isinstance(selected, bool):
                return HttpResponseBadRequest('参数有误')

        user = request.user

        # 判断是否是匿名用户
        if not user.is_authenticated:
            # cookie逻辑
            # 判断用户是否已有购物车
            carts_str = request.COOKIES.get('carts')
            if carts_str:
                # 将数据解密
                carts_dict = pickle.loads(base64.b64decode(carts_str.encode()))
                #　carts_dict = {1: {count: 2, selected: True}, 2:{count: 1, selected: True}}
            else:
                # 创建一个购物车用于存储数据

                carts_dict = {}

            # 判断商品id是否在字典中
            if sku_id in carts_dict:
                # 在就累加
                carts_dict[sku_id]['count'] = count
                carts_dict[sku_id]['selected'] = selected
            else:
                # 不在就添加
                carts_dict[sku_id] = {
                    'count': count,
                    'selected': selected
                }

            # 加密数据
            carts_str = base64.b64encode(pickle.dumps(carts_dict)).decode()

            # 设置cookie
            response = JsonResponse({'code': 0,
                                    'errmsg': 'ok'})
            response.set_cookie('carts', carts_str, max_age=7*24*3600)
            return response




        else:
            # redis逻辑
            redis_conn = get_redis_connection('carts')

            '''u2 name itcast age 11'''
            # 用哈希的方法
            pl = redis_conn.pipeline()
            pl.hincrby('carts_%s' % user.id, sku_id, count)

            if selected:
                pl.sadd('selectid_%s' % user.id, sku_id)

            pl.execute()






            # 响应
            return JsonResponse({'code': 0,
                                'errmsg': 'ok'})